home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / UNIX / PASCAL / PTOC / PTC_P.4 < prev    next >
Text File  |  1992-11-23  |  54KB  |  2,234 lines

  1.                     end
  2.             until    tq = nil;
  3.         555:
  4.             writeln(';');
  5.             if tp^.tt = nvarpar then
  6.                 if tp^.tbind^.tt = nconfarr then
  7.                     begin
  8.                     indent;
  9.                     etypedef(tp^.tbind^.tindtyp);
  10.                     write(tab1);
  11.                     tq := tp^.tbind^.tcindx^.thi;
  12.                     printid(tq^.tsym^.lid);
  13.                     writeln(';')
  14.                     end;
  15.             tp := tp^.tnext
  16.             end
  17.     end;    (* evar *)
  18.  
  19.     (*    Emit code for a statment.                *)
  20.     procedure estmt(tp : treeptr);
  21.  
  22.     var    tq    : treeptr;
  23.         locid1,
  24.         locid2    : idptr;
  25.         stusd    : boolean;
  26.         opc1,
  27.         opc2    : char;
  28.  
  29.         (*    Emit typename for with-variable.        *)
  30.         procedure ewithtype(tp : treeptr);
  31.  
  32.         var    tq    : treeptr;
  33.  
  34.         begin
  35.             tq := typeof(tp);
  36.             write('struct ');
  37.             printid(tq^.tuid)
  38.         end;
  39.  
  40.         (*    Emit code for a case-choise.        *)
  41.         procedure echoise(tp : treeptr);
  42.  
  43.         var    tq    : treeptr;
  44.             i    : integer;
  45.  
  46.         begin
  47.             while tp <> nil do
  48.                 begin
  49.                 tq := tp^.tchocon;
  50.                 i := 0;
  51.                 indent;
  52.                 while tq <> nil do
  53.                     begin
  54.                     write('  case ');
  55.                     conflag := true;
  56.                     eexpr(tq);
  57.                     conflag := false;
  58.                     write(':');
  59.                     i := i + 1;
  60.                     tq := tq^.tnext;
  61.                     if (tq = nil) or (i mod 4 = 0) then
  62.                         begin
  63.                         writeln;
  64.                         if tq <> nil then
  65.                             indent;
  66.                         i := 0
  67.                         end
  68.                     end;
  69.                 increment;
  70.                 if tp^.tchostmt^.tt = nbegin then
  71.                     estmt(tp^.tchostmt^.tbegin)
  72.                 else
  73.                     estmt(tp^.tchostmt);
  74.                 indent;
  75.                 writeln('break ;');
  76.                 decrement;
  77.                 tp := tp^.tnext;
  78.                 if tp <> nil then
  79.                     if tp^.tchocon = nil then
  80.                         tp := nil
  81.                 end
  82.         end;    (* echoise *)
  83.  
  84.         (*    Rename all accessible record-fields to include    *)
  85.         (*    pointer name.                    *)
  86.         procedure cenv(ip : idptr; dp : declptr);
  87.  
  88.         var    tp    : treeptr;
  89.             sp    : symptr;
  90.             np    : idptr;
  91.             h    : hashtyp;
  92.  
  93.         begin
  94.             with dp^ do
  95.               for h := 0 to hashmax - 1 do
  96.                 begin
  97.                 sp := ddecl[h];
  98.                 while sp <> nil do
  99.                     begin
  100.                     if sp^.lt = lfield  then
  101.                         begin
  102.                         np := sp^.lid;
  103.                         tp := sp^.lsymdecl^.tup^.tup;
  104.                         if (tp^.tup^.tt = nvariant) and
  105.                             (tp^.tuid <> nil) then
  106.                             np := mkconc('.',
  107.                                 tp^.tuid, np);
  108.                         np := mkconc('>', ip, np);
  109.                         sp^.lid := np
  110.                         end;
  111.                     sp := sp^.lnext
  112.                     end
  113.                 end
  114.         end;    (* cenv *)
  115.  
  116.         (*    Emit identifiers for push/pop of global ptrs.    *)
  117.         procedure eglobid(tp : treeptr);
  118.  
  119.         var    j    : toknidx;
  120.             w    : toknbuf;
  121.  
  122.         begin
  123.             gettokn(tp^.tsym^.lid^.istr, w);
  124.             j := 1;
  125.             if w[1] = '*' then
  126.                 j := 2;
  127.             while w[j] <> chr(null) do
  128.                 begin
  129.                 write(w[j]);
  130.                 j := j + 1
  131.                 end
  132.         end;
  133.  
  134.     begin    (* estmt *)
  135.         while tp <> nil do
  136.             begin
  137.             case tp^.tt of
  138.               nbegin:
  139.                 begin
  140.                 if tp^.tup^.tt in [nbegin, nrepeat,
  141.                         nproc, nfunc, npgm] then
  142.                     indent;
  143.                 writeln('{');
  144.                 increment;
  145.                 estmt(tp^.tbegin);
  146.                 decrement;
  147.                 indent;
  148.                 write('}');
  149.                 if tp^.tup^.tt <> nif then
  150.                     writeln
  151.                 end;
  152.               nrepeat:
  153.                 begin
  154.                 indent;
  155.                 writeln('do {');
  156.                 increment;
  157.                 estmt(tp^.treptstmt);
  158.                 decrement;
  159.                 indent;
  160.                 write('} while (!(');
  161.                 eexpr(tp^.treptxp);
  162.                 writeln('));')
  163.                 end;
  164.               nwhile:
  165.                 begin
  166.                 indent;
  167.                 write('while (');
  168.                 increment;
  169.                 eexpr(tp^.twhixp);
  170.                 stusd := setused;
  171.                 if tp^.twhistmt^.tt = nbegin then
  172.                     begin
  173.                     decrement;
  174.                     write(') ');
  175.                     estmt(tp^.twhistmt)
  176.                     end
  177.                 else begin
  178.                     writeln(')');
  179.                     estmt(tp^.twhistmt);
  180.                     decrement
  181.                      end;
  182.                 setused := stusd or setused
  183.                 end;
  184.               nfor:
  185.                 begin
  186.                 indent;
  187.                 if tp^.tincr then
  188.                     begin
  189.                     opc1 := '+';    (* increment variable *)
  190.                     opc2 := '<'    (* test for <= *)
  191.                     end
  192.                 else begin
  193.                     opc1 := '-';    (* decrement variable *)
  194.                     opc2 := '>';    (* test for >= *)
  195.                      end;
  196.                 if not lazyfor then
  197.                     begin
  198.                     locid1 := mkvariable('B');
  199.                     locid2 := mkvariable('B');
  200.                     writeln('{');
  201.                     increment;
  202.                     indent;
  203.                     tq := idup(tp^.tforid);
  204.                     etypedef(tq^.tbind);
  205.                     tq := typeof(tq^.tbind);
  206.                     write(tab1);
  207.                     printid(locid1);
  208.                     write(' = ');
  209.                     eexpr(tp^.tfrom);
  210.                     writeln(',');
  211.                     indent;
  212.                     write(tab1);
  213.                     printid(locid2);
  214.                     write(' = ');
  215.                     eexpr(tp^.tto);
  216.                     writeln(';');
  217.                     writeln;
  218.                     indent;
  219.                     write('if (');
  220.                     if tq^.tt = nscalar then
  221.                         begin
  222.                         write('(int)(');
  223.                         printid(locid1);
  224.                         write(')')
  225.                         end
  226.                     else
  227.                         printid(locid1);
  228.                     write(' ', opc2, '= ');
  229.                     if tq^.tt = nscalar then
  230.                         begin
  231.                         write('(int)(');
  232.                         printid(locid2);
  233.                         write(')')
  234.                         end
  235.                     else
  236.                         printid(locid2);
  237.                     writeln(')');
  238.                     increment;
  239.                     indent;
  240.                     tp^.tfrom := newid(locid1);
  241.                     tp^.tfrom^.tup := tp
  242.                     end;
  243.                 write('for (');
  244.                 increment;
  245.                 eexpr(tp^.tforid);
  246.                 tq := typeof(tp^.tforid);
  247.                 write(' = ');
  248.                 eexpr(tp^.tfrom);
  249.                 write('; ');
  250.                 if lazyfor then
  251.                     begin
  252.                     if tq^.tt = nscalar then
  253.                         begin
  254.                         write('(int)(');
  255.                         eexpr(tp^.tforid);
  256.                         write(')')
  257.                         end
  258.                     else
  259.                         eexpr(tp^.tforid);
  260.                     write(' ', opc2, '= ');
  261.                     if tq^.tt = nscalar then
  262.                         begin
  263.                         write('(int)(');
  264.                         eexpr(tp^.tto);
  265.                         write(')')
  266.                         end
  267.                     else
  268.                         eexpr(tp^.tto)
  269.                     end;
  270.                 write('; ');
  271.                 eexpr(tp^.tforid);
  272.                 if tq^.tt = nscalar then
  273.                     begin
  274.                     write(' = (');
  275.                     eexpr(tq^.tup^.tidl);
  276.                     write(')((int)(');
  277.                     eexpr(tp^.tforid);
  278.                     write(')', opc1, '1)')
  279.                     end
  280.                 else
  281.                     write(opc1, opc1);
  282.                 if not lazyfor then
  283.                     begin
  284.                     if tp^.tforstmt^.tt <> nbegin then
  285.                         begin
  286.                         (* create compund stmt *)
  287.                         tq := mknode(nbegin);
  288.                         tq^.tbegin := tp^.tforstmt;
  289.                         tq^.tbegin^.tup := tq;
  290.                         tp^.tforstmt := tq;
  291.                         tq^.tup := tp
  292.                         end;
  293.                     (* find end of loop *)
  294.                     tq := tp^.tforstmt^.tbegin;
  295.                     while tq^.tnext <> nil do
  296.                         tq := tq^.tnext;
  297.                     (* add break stmt *)
  298.                     tq^.tnext := mknode(nbreak);
  299.                     tq := tq^.tnext;
  300.                     tq^.tup := tp^.tforstmt;
  301.                     tq^.tbrkid := tp^.tforid;
  302.                     tq^.tbrkxp := newid(locid2);
  303.                     tq^.tbrkxp^.tup := tq
  304.                     end;
  305.                 if tp^.tforstmt^.tt = nbegin then
  306.                     begin
  307.                     decrement;
  308.                     write(') ');
  309.                     estmt(tp^.tforstmt)
  310.                     end
  311.                 else begin
  312.                     writeln(')');
  313.                     estmt(tp^.tforstmt);
  314.                     decrement
  315.                      end;
  316.                 if not lazyfor then
  317.                     begin
  318.                     decrement;
  319.                     decrement;
  320.                     indent;
  321.                     writeln('}')
  322.                     end
  323.                 end;
  324.               nif:
  325.                 begin
  326.                 indent;
  327.                 write('if (');
  328.                 increment;
  329.                 eexpr(tp^.tifxp);
  330.                 stusd := setused;
  331.                 setused := false;
  332.                 if tp^.tthen^.tt = nbegin then
  333.                     begin
  334.                     decrement;
  335.                     write(') ');
  336.                     estmt(tp^.tthen);
  337.                     if tp^.telse <> nil then
  338.                         write(space)
  339.                     else
  340.                         writeln
  341.                     end
  342.                 else begin
  343.                     writeln(')');
  344.                     estmt(tp^.tthen);
  345.                     decrement;
  346.                     if tp^.telse <> nil then
  347.                         indent
  348.                      end;
  349.                 if tp^.telse <> nil then
  350.                     begin
  351.                     write('else');
  352.                     if tp^.telse^.tt = nbegin then
  353.                         begin
  354.                         write(space);
  355.                         estmt(tp^.telse);
  356.                         writeln
  357.                         end
  358.                     else begin
  359.                         increment;
  360.                         writeln;
  361.                         estmt(tp^.telse);
  362.                         decrement
  363.                          end;
  364.                     end;
  365.                 setused := stusd or setused
  366.                 end;
  367.               ncase:
  368.                 begin
  369.                 indent;
  370.                 write('switch (');
  371.                 increment;
  372.                 eexpr(tp^.tcasxp);
  373.                 writeln(') {');
  374.                 decrement;
  375.                 echoise(tp^.tcaslst);
  376.                 indent;
  377.                 writeln('  default:');
  378.                 increment;
  379.                 if tp^.tcasother = nil then
  380.                     begin
  381.                     indent;
  382.                     writeln('Caseerror(Line);')
  383.                     end
  384.                 else
  385.                     estmt(tp^.tcasother);
  386.                 decrement;
  387.                 indent;
  388.                 writeln('}')
  389.                 end;
  390.               nwith:
  391.                 begin
  392.                 indent;
  393.                 writeln('{');
  394.                 increment;
  395.                 tq := tp^.twithvar;
  396.                 while tq <> nil do
  397.                     begin
  398.                     indent;
  399.                     write(registr);
  400.                     ewithtype(tq^.texpw);
  401.                     write(' *');
  402.                     locid1 := mkvariable('W');
  403.                     printid(locid1);
  404.                     write(' = ');
  405.                     eaddr(tq^.texpw);
  406.                     writeln(';');
  407.                     cenv(locid1, tq^.tenv);
  408.                     tq := tq^.tnext
  409.                     end;
  410.                 writeln;
  411.                 if tp^.twithstmt^.tt = nbegin then
  412.                     estmt(tp^.twithstmt^.tbegin)
  413.                 else
  414.                     estmt(tp^.twithstmt);
  415.                 decrement;
  416.                 indent;
  417.                 writeln('}')
  418.                 end;
  419.               ngoto:
  420.                 begin
  421.                 indent;
  422.                 if islocal(tp^.tlabel) then
  423.                     writeln('goto L',
  424.                         tp^.tlabel^.tsym^.lno:1, ';')
  425.                 else begin
  426.                     tq := idup(tp^.tlabel);
  427.                     writeln('longjmp(J[',    (* LIB *)
  428.                         tq^.tstat:1, '].jb, ',
  429.                         tp^.tlabel^.tsym^.lno:1, ');')
  430.                      end
  431.                 end;
  432.               nlabstmt:
  433.                 begin
  434.                 decrement;
  435.                 indent;
  436.                 writeln('L', tp^.tlabno^.tsym^.lno:1, ':');
  437.                 increment;
  438.                 estmt(tp^.tstmt)
  439.                 end;
  440.               nassign:
  441.                 begin
  442.                 indent;
  443.                 eexpr(tp);
  444.                 writeln(';')
  445.                 end;
  446.               ncall:
  447.                 begin
  448.                 indent;
  449.                 tq := idup(tp^.tcall);
  450.                 if (tq^.tt in [nfunc, nproc]) and
  451.                         (tq^.tsubstmt <> nil) then
  452.                     if tq^.tsubstmt^.tt = npredef then
  453.                         epredef(tq, tp)
  454.                     else begin
  455.                         ecall(tp);
  456.                         writeln(';')
  457.                          end
  458.                 else begin
  459.                     ecall(tp);
  460.                     writeln(';')
  461.                      end
  462.                 end;
  463.               npush:
  464.                 begin
  465.                 indent;
  466.                 eglobid(tp^.ttmp);
  467.                 write(' = ');
  468.                 eglobid(tp^.tglob);
  469.                 writeln(';');
  470.                 indent;
  471.                 eglobid(tp^.tglob);
  472.                 write(' = ');
  473.                 if tp^.tloc^.tt = nid then
  474.                     begin
  475.                     tq := idup(tp^.tloc);
  476.                     if tq^.tt in [nparproc, nparfunc] then
  477.                         printid(tp^.tloc^.tsym^.lid)
  478.                     else
  479.                         eaddr(tp^.tloc)
  480.                     end
  481.                 else
  482.                     eaddr(tp^.tloc);
  483.                 writeln(';')
  484.                 end;
  485.               npop:
  486.                 begin
  487.                 indent;
  488.                 eglobid(tp^.tglob);
  489.                 write(' = ');
  490.                 eglobid(tp^.ttmp);
  491.                 writeln(';')
  492.                 end;
  493.               nbreak:
  494.                 begin
  495.                 indent;
  496.                 write('if (');
  497.                 eexpr(tp^.tbrkid);
  498.                 write(' == ');
  499.                 eexpr(tp^.tbrkxp);
  500.                 writeln(') break;')
  501.                 end;
  502.               nempty:
  503.                 if not (tp^.tup^.tt in [npgm, nproc, nfunc,
  504.                         nchoise, nbegin, nrepeat]) then
  505.                     begin
  506.                     indent;
  507.                     writeln(';')
  508.                     end
  509.             end;(* case *)
  510.             if setused and
  511.                 (tp^.tup^.tt in [npgm, nproc, nfunc, nrepeat,
  512.                         nbegin, nchoise, nwith]) then
  513.                 begin
  514.                 indent;
  515.                 writeln('Claimset();');
  516.                 setused := false
  517.                 end;
  518.             tp := tp^.tnext
  519.             end
  520.     end;    (* estmt *)
  521.  
  522.     (*    Emit initialization for non-local gotos.        *)
  523.     procedure elabel(tp : treeptr);
  524.  
  525.     var    tq    : treeptr;
  526.         i    : integer;
  527.  
  528.     begin
  529.         i := 0;
  530.         tq := tp^.tsublab;
  531.         while tq <> nil do
  532.             begin
  533.             if tq^.tsym^.lgo then
  534.                 i := i + 1;
  535.             tq := tq^.tnext
  536.             end;
  537.         if i =1 then
  538.             begin
  539.             tq := tp^.tsublab;
  540.             while not tq^.tsym^.lgo do
  541.                 tq := tq^.tnext;
  542.             indent;
  543.             writeln('if (',
  544.                 'setjmp(J[', tp^.tstat:1, '].jb))'); (* LIB *)
  545.             writeln(tab1, 'goto L', tq^.tsym^.lno:1, ';')
  546.             end
  547.         else if i > 1 then
  548.             begin
  549.             indent;
  550.             writeln('switch (',
  551.                 'setjmp(J[', tp^.tstat:1, '].jb)) {'); (* LIB *)
  552.             indent;
  553.             writeln('  case 0:');
  554.             indent;
  555.             writeln(tab1, 'break');
  556.             tq := tp^.tsublab;
  557.             while tq <> nil do
  558.                 begin
  559.                 if tq^.tsym^.lgo then
  560.                     begin
  561.                     (* label used in non-local goto *)
  562.                     indent;
  563.                     writeln('  case ',
  564.                             tq^.tsym^.lno:1, ':');
  565.                     indent;
  566.                     writeln(tab1, 'goto L',
  567.                             tq^.tsym^.lno:1, ';')
  568.                     end;
  569.                 tq := tq^.tnext
  570.                 end;
  571.             indent;
  572.             writeln('  default:');
  573.             indent;
  574.             writeln(tab1, 'Caseerror(Line)');
  575.             indent;
  576.             writeln('}')
  577.             end
  578.     end;    (* elabel *)
  579.  
  580.     (*    Emit declaration for lower bound of conformant array.    *)
  581.     procedure econf(tp : treeptr);
  582.  
  583.     var    tq    : treeptr;
  584.  
  585.     begin
  586.         while tp <> nil do
  587.             begin
  588.             if tp^.tt = nvarpar then
  589.                 if tp^.tbind^.tt = nconfarr then
  590.                     begin
  591.                     indent;
  592.                     etypedef(tp^.tbind^.tindtyp);
  593.                     write(tab1);
  594.                     tq := tp^.tbind^.tcindx^.tlo;
  595.                     printid(tq^.tsym^.lid);
  596.                     write(' = (');
  597.                     etypedef(tp^.tbind^.tindtyp);
  598.                     writeln(')0;')
  599.                     end;
  600.             tp := tp^.tnext
  601.             end
  602.     end;    (* econf *)
  603.  
  604.     (*    Emit code for subroutines.                *)
  605.     procedure esubr(tp : treeptr);
  606.  
  607.     label    999;
  608.  
  609.     var    tq, ti    : treeptr;
  610.  
  611.     begin
  612.         while tp <> nil do
  613.             begin
  614.             (* emit nested subroutines *)
  615.             if tp^.tsubsub <> nil then
  616.                 begin
  617.                 (* emit forward declaration of this subroutine
  618.                    in case of recursion *)
  619.                 etypedef(tp^.tfuntyp);
  620.                 write(space);
  621.                 printid(tp^.tsubid^.tsym^.lid);
  622.                 writeln('();');
  623.                 writeln;
  624.                 esubr(tp^.tsubsub)
  625.                 end;
  626.             (* emit this subroutine *)
  627.             if tp^.tsubstmt = nil then
  628.                 begin
  629.                 (* forward/external decl *)
  630.                 if tp^.tsubid^.tsym^.lsymdecl^.tup = tp then
  631.                     write(xtern);
  632.                 etypedef(tp^.tfuntyp);
  633.                 write(space);
  634.                 printid(tp^.tsubid^.tsym^.lid);
  635.                 writeln('();');
  636.                 goto 999
  637.                 end;
  638.             write(space);
  639.             etypedef(tp^.tfuntyp);
  640.             writeln;
  641.             printid(tp^.tsubid^.tsym^.lid);
  642.             write('(');
  643.             tq := tp^.tsubpar;
  644.             while tq <> nil do
  645.                 begin
  646.                 case tq^.tt of
  647.                   nvarpar,
  648.                   nvalpar:
  649.                     begin
  650.                     ti := tq^.tidl;
  651.                     while ti <> nil do
  652.                         begin
  653.                         printid(ti^.tsym^.lid);
  654.                         ti := ti^.tnext;
  655.                         if ti <> nil then
  656.                             write(', ');
  657.                         end;
  658.                     if tq^.tbind^.tt = nconfarr then
  659.                         begin
  660.                         (* add upper bound parameter *)
  661.                         ti := tq^.tbind^.tcindx^.thi;
  662.                         write(', ');
  663.                         printid(ti^.tsym^.lid)
  664.                         end;
  665.                     end;
  666.                   nparproc,
  667.                   nparfunc:
  668.                     begin
  669.                     ti := tq^.tparid;
  670.                     printid(ti^.tsym^.lid)
  671.                     end
  672.                 end;(* case *)
  673.                 tq := tq^.tnext;
  674.                 if tq <> nil then
  675.                     write(', ');
  676.                 end;
  677.             writeln(')');
  678.             increment;
  679.             evar(tp^.tsubpar);
  680.             writeln('{');
  681.             econf(tp^.tsubpar);
  682.             econst(tp^.tsubconst);
  683.             etype(tp^.tsubtype);
  684.             evar(tp^.tsubvar);
  685.  
  686.             if (tp^.tsubconst <> nil) or (tp^.tsubtype <> nil) or
  687.                     (tp^.tsubvar <> nil) then
  688.                 writeln;
  689.             elabel(tp);
  690.             estmt(tp^.tsubstmt);
  691.             if tp^.tt = nfunc then
  692.                 begin
  693.                 (* return value in the FIRST variable,
  694.                    see renamf() above *)
  695.                 indent;
  696.                 write('return ');
  697.                 printid(tp^.tsubvar^.tidl^.tsym^.lid);
  698.                 writeln(';');
  699.                 end;
  700.             decrement;
  701.             writeln('}');
  702.         999:
  703.             writeln;
  704.             tp := tp^.tnext
  705.             end
  706.     end;    (* esubr *)
  707.  
  708.     function use(d : predefs) : boolean;
  709.  
  710.     begin
  711.         use := defnams[d]^.lused
  712.     end;
  713.  
  714.     (*    Emit code for main program.                *)
  715.     procedure eprogram(tp : treeptr);
  716.  
  717.         (*    Symbol that sp refers to is renamed if it has    *)
  718.         (*    been redefined in source program.        *)
  719.         procedure capital(sp : symptr);
  720.  
  721.         var    tb    : toknbuf;
  722.  
  723.         begin
  724.             if sp^.lid^.inref > 1 then
  725.                 begin
  726.                 gettokn(sp^.lid^.istr, tb);
  727.                 tb[1] := uppercase(tb[1]);
  728.                 sp^.lid := saveid(tb)
  729.                 end
  730.         end;
  731.  
  732.         procedure etextdef;
  733.  
  734.         var    tq    : treeptr;
  735.  
  736.         begin
  737.             write('typedef ');
  738.             tq := mknode(nfileof);
  739.             tq^.tof := typnods[tchar];
  740.             etypedef(tq);
  741.             writeln(tab1, 'text;')
  742.         end;
  743.  
  744.     begin    (* eprogram *)
  745.         if tp^.tsubid <> nil then
  746.             begin
  747.             (* program heading was seen *)
  748.             writeln('/', '*');
  749.             write('**    Code derived from program ');
  750.             printid(tp^.tsubid^.tsym^.lid);
  751.             writeln;
  752.             writeln('*', '/');
  753.             writeln(xtern, voidtyp, tab1, 'exit();')
  754.             end;
  755.         if usecase or usesets or
  756.            use(dinput) or use(doutput) or
  757.            use(dwrite) or use(dwriteln) or use(dmessage) or
  758.            use(deof) or use(deoln) or use(dflush) or use(dpage) or
  759.            use(dread) or use(dreadln) or use(dclose) or
  760.            use(dreset) or use(drewrite) or use(dget) or use(dput) then
  761.             begin
  762.             writeln('/', '*');
  763.             writeln('**    Definitions for i/o');
  764.             writeln('*', '/');
  765.             writeln(include, '<stdio.h>')    (* LIB *)
  766.             end;
  767.         if use(dinput) or use(doutput) or use(dtext) then
  768.             begin
  769.             etextdef;
  770.             if use(dinput) then
  771.                 begin
  772.                 if tp^.tsubid = nil then
  773.                     write(xtern);
  774.                 write('text', tab1);
  775.                 printid(defnams[dinput]^.lid);
  776.                 if tp^.tsubid <> nil then
  777.                     write(' = { stdin, 0, 0 }');
  778.                 writeln(';')
  779.                 end;
  780.             if use(doutput) then
  781.                 begin
  782.                 if tp^.tsubid = nil then
  783.                     write(xtern);
  784.                 write('text', tab1);
  785.                 printid(defnams[doutput]^.lid);
  786.                 if tp^.tsubid <> nil then
  787.                     write(' = { stdout, 0, 0 }');
  788.                 writeln(';')
  789.                 end
  790.             end;
  791.         if use(dinput) or use(dget) or use(dread) or use(dreadln) or
  792.            use(deof) or use(deoln) or use(dreset) or use(drewrite) then
  793.             begin
  794.             writeln(define, 'Fread(x, f) ',
  795.                 'fread((char *)&x, sizeof(x), 1, f)'); (* LIB *)
  796.             writeln(define, 'Get(f) Fread((f).buf, (f).fp)');
  797.             writeln(define, 'Getx(f) (f).init = 1, ',
  798.                 '(f).eoln = (((f).buf = ',
  799.                     'fgetc((f).fp)',    (* LIB *)
  800.                     ') == ', nlchr, ') ? (((f).buf = ',
  801.                         spchr, '), 1) : 0');
  802.             writeln(define, 'Getchr(f) (f).buf, Getx(f)')
  803.             end;
  804.         if use(dread) or use(dreadln) then
  805.             begin
  806.             writeln(static, 'FILE', tab1, '*Tmpfil;');
  807.             writeln(static, 'long', tab1, 'Tmplng;');
  808.             writeln(static, 'double', tab1, 'Tmpdbl;');
  809.             writeln(define, 'Fscan(f) (f).init ? ',
  810.                 'ungetc((f).buf, (f).fp)',    (* LIB *)
  811.                     ' : 0, Tmpfil = (f).fp');
  812.             writeln(define, 'Scan(p, a) ',
  813.                 'Scanck(fscanf(Tmpfil, p, a))'); (* LIB *)
  814.             writeln(voidtyp, tab1, 'Scanck();');
  815.             if use(dreadln) then
  816.                 writeln(voidtyp, tab1, 'Getl();');
  817.             end;
  818.         if use(deoln) then
  819.             writeln(define, 'Eoln(f) ((f).eoln ? true : false)');
  820.         if use(deof) then
  821.             writeln(define, 'Eof(f) ',
  822.                 '((((f).init == 0) ? (Get(f)) : 0, ',
  823.                     '((f).eof ? 1 : ',
  824.                         'feof((f).fp))) ? ', (* LIB *)
  825.                             'true : false)');
  826.         if use(doutput) or use(dput) or
  827.                 use(dwrite) or use(dwriteln) or
  828.                 use(dreset) or use(drewrite) or use(dclose) then
  829.             begin
  830.             writeln(define, 'Fwrite(x, f) ',
  831.                 'fwrite((char *)&x, sizeof(x), 1, f)');(* LIB *)
  832.             writeln(define, 'Put(f) Fwrite((f).buf, (f).fp)');
  833.             writeln(define, 'Putx(f) (f).eoln = ((f).buf == ',
  834.                 nlchr, '), ', voidcast,
  835.                 'fputc((f).buf, (f).fp)'); (* LIB *)
  836.             writeln(define, 'Putchr(c, f) (f).buf = (c), Putx(f)');
  837.             writeln(define, 'Putl(f, v) (f).eoln = v')
  838.             end;
  839.         if use(dreset) or use(drewrite) or use(dclose) then
  840.             writeln(define, 'Finish(f) ((f).out && !(f).eoln) ? ',
  841.                 '(Putchr(', nlchr, ', f), 0) : 0, ',
  842.                     'rewind((f).fp)');    (* LIB *)
  843.         if use(dclose) then
  844.             begin
  845.             writeln(define, 'Close(f) (f).init = ',
  846.                 '((f).init ? (',
  847.                     'fclose((f).fp), ',    (* LIB *)
  848.                         '0) : 0), (f).fp = NULL');
  849.             writeln(define, 'Closex(f) (f).init = ',
  850.                 '((f).init ? ',
  851.                     '(Finish(f), ',
  852.                     'fclose((f).fp), ',    (* LIB *)
  853.                         '0) : 0), (f).fp = NULL')
  854.             end;
  855.         if use(dreset) then
  856.             begin
  857.             writeln(ifdef, 'READONLY');
  858.             writeln(static, chartyp, tab1, 'Rmode[] = "r";');
  859.             writeln(elsif);
  860.             writeln(static, chartyp, tab1, 'Rmode[] = "r+";');
  861.             writeln(endif);
  862.             writeln(define, 'Reset(f, n) (f).init = ',
  863.                 '(f).init ? rewind((f).fp) : ',    (* LIB *)
  864.                 '(((f).fp = Fopen(n, Rmode)), 1), ',
  865.                     '(f).eof = (f).out = 0, Get(f)');
  866.             writeln(define, 'Resetx(f, n) (f).init = ',
  867.                 '(f).init ? (Finish(f)) : ',
  868.                 '(((f).fp = Fopen(n, Rmode)), 1), ',
  869.                     '(f).eof = (f).out = 0, Getx(f)');
  870.             usefopn := true
  871.             end;
  872.         if use(drewrite) then
  873.             begin
  874.             writeln(ifdef, 'WRITEONLY');
  875.             writeln(static, chartyp, tab1, 'Wmode[] = "w";');
  876.             writeln(elsif);
  877.             writeln(static, chartyp, tab1, 'Wmode[] = "w+";');
  878.             writeln(endif);
  879.             writeln(define, 'Rewrite(f, n) (f).init = ',
  880.                 '(f).init ? rewind((f).fp) : ',    (* LIB *)
  881.                 '(((f).fp = Fopen(n, Wmode)), 1), ',
  882.                     '(f).out = (f).eof = 1');
  883.             writeln(define, 'Rewritex(f, n) (f).init = ',
  884.                 '(f).init ? (Finish(f)) : ',
  885.                 '(((f).fp = Fopen(n, Wmode)), 1), ',
  886.                     '(f).out = (f).eof = (f).eoln = 1');
  887.             usefopn := true
  888.             end;
  889.         if usefopn then
  890.             begin
  891.             writeln('FILE    *Fopen();');
  892.             writeln(define, 'MAXFILENAME 256')
  893.             end;
  894.         if usecase or usejmps then
  895.             begin
  896.             writeln('/', '*');
  897.             writeln('**    Definitions for case-statements');
  898.             writeln('**    and for non-local gotos');
  899.             writeln('*', '/');
  900.             writeln(define, 'Line __LINE__');
  901.             writeln(voidtyp, tab1, 'Caseerror();')
  902.             end;
  903.         if usejmps then
  904.             begin
  905.             writeln(include, '<setjmp.h>');    (* LIB *)
  906.             writeln(static, 'struct Jb { jmp_buf', tab1, 'jb; } J[',
  907.                             (maxlevel+1):1, '];')
  908.             end;
  909.         if use(dinteger) or use(dmaxint) or 
  910.             use(dboolean) or use(dfalse) or use(dtrue) or
  911.                 use(deof) or use(deoln) or use(dexp) or
  912.                 use(dln) or use(dsqr) or use(dsin) or
  913.                 use(dcos) or use(dtan) or use(darctan) or
  914.                 use(dsqrt) or use(dreal) then
  915.             begin
  916.             writeln('/', '*');
  917.             writeln('**    Definitions for standard types');
  918.             writeln('*', '/')
  919.             end;
  920.         if usecomp then
  921.             begin
  922.             writeln(xtern, inttyp, ' strncmp();');    (* LIB *)
  923.             writeln(define,
  924.                 'Cmpstr(x, y) ',
  925.                 'strncmp((x), (y), sizeof(x))')    (* LIB *)
  926.             end;
  927.         if use(dboolean) or use(dfalse) or use(dtrue) or
  928.             use(deof) or use(deoln) or usesets then
  929.             begin
  930.             capital(defnams[dboolean]);
  931.             write(typdef, chartyp, tab1);
  932.             printid(defnams[dboolean]^.lid);
  933.             writeln(';');
  934.             capital(defnams[dfalse]);
  935.             write(define);
  936.             printid(defnams[dfalse]^.lid);
  937.             write(' (');
  938.             printid(defnams[dboolean]^.lid);
  939.             writeln(')0');
  940.             capital(defnams[dtrue]);
  941.             write(define);
  942.             printid(defnams[dtrue]^.lid);
  943.             write(' (');
  944.             printid(defnams[dboolean]^.lid);
  945.             writeln(')1');
  946.             writeln(xtern, chartyp, tab1, '*Bools[];')
  947.             end;
  948.         capital(defnams[dinteger]);
  949.         if use(dinteger) then
  950.             begin
  951.             write(typdef, inttyp, tab1);
  952.             printid(defnams[dinteger]^.lid);
  953.             writeln(';')
  954.             end;
  955.         if use(dmaxint) then
  956.             writeln(define, 'maxint', tab1, maxint:1);
  957.         capital(defnams[dreal]);
  958.         if use(dreal) then
  959.             begin
  960.             write(typdef, realtyp, tab1);
  961.             printid(defnams[dreal]^.lid);
  962.             writeln(';')
  963.             end;
  964.         if use(dexp) then
  965.             writeln(xtern, doubletyp, ' exp();');    (* LIB *)
  966.         if use(dln) then
  967.             writeln(xtern, doubletyp, ' log();');    (* LIB *)
  968.         if use(dsqr) then
  969.             writeln(xtern, doubletyp, ' pow();');    (* LIB *)
  970.         if use(dsin) then
  971.             writeln(xtern, doubletyp, ' sin();');    (* LIB *)
  972.         if use(dcos) then
  973.             writeln(xtern, doubletyp, ' cos();');    (* LIB *)
  974.         if use(dtan) then
  975.             writeln(xtern, doubletyp, ' tan();');    (* LIB *)
  976.         if use(darctan) then
  977.             writeln(xtern, doubletyp, ' atan();');    (* LIB *)
  978.         if use(dsqrt) then
  979.             writeln(xtern, doubletyp, ' sqrt();');    (* LIB *)
  980.         if use(dabs) and use(dreal) then
  981.             writeln(xtern, doubletyp, ' fabs();');    (* LIB *)
  982.         if use(dhalt) then
  983.             writeln(xtern, voidtyp, ' abort();');    (* LIB *)
  984.         if use(dnew) or usenilp then
  985.             begin
  986.             writeln('/', '*');
  987.             writeln('**    Definitions for pointers');
  988.             writeln('*', '/');
  989.             end;
  990.         if use(dnew) then
  991.             begin
  992.             writeln(ifndef, 'Unionoffs');
  993.             writeln(define, 'Unionoffs(p, m) ',
  994.                 '(((long)(&(p)->m))-((long)(p)))');    (* CPU *)
  995.             writeln(endif)
  996.             end;
  997.         if usenilp then
  998.             writeln(define, 'NIL 0');        (* CPU *)
  999.         if use(dnew) then
  1000.             writeln(xtern, chartyp, ' *malloc();');    (* LIB *)
  1001.         if use(ddispose) then
  1002.             writeln(xtern, voidtyp, ' free();');    (* LIB *)
  1003.         if usesets then
  1004.             begin
  1005.             writeln('/', '*');
  1006.             writeln('**    Definitions for set-operations');
  1007.             writeln('*', '/');
  1008.             writeln(define, 'Claimset() ',
  1009.                 voidcast, 'Currset(0, (', setptyp, ')0)');
  1010.             writeln(define, 'Newset() ',
  1011.                     'Currset(1, (', setptyp, ')0)');
  1012.             writeln(define, 'Saveset(s) Currset(2, s)');
  1013.             writeln(define, 'setbits ', setbits:1);
  1014.             writeln(typdef, wordtype, tab1, setwtyp, ';');
  1015.             writeln(typdef, setwtyp, ' *', tab1, setptyp, ';');
  1016.             printid(defnams[dboolean]^.lid);
  1017.             writeln(tab1, 'Member(), Le(), Ge(), Eq(), Ne();');
  1018.             writeln(setptyp, tab1, 'Union(), Diff();');
  1019.             writeln(setptyp, tab1, 'Insmem(), Mksubr();');
  1020.             writeln(setptyp, tab1, 'Currset(), Inter();');
  1021.             writeln(static, setptyp, tab1, 'Tmpset;');
  1022.             writeln(xtern, setptyp, tab1, 'Conset[];');
  1023.             writeln(voidtyp, tab1, 'Setncpy();')
  1024.             end;
  1025.         writeln(xtern, chartyp, ' *strncpy();');    (* LIB *)
  1026.         if use(dargc) or use(dargv) then
  1027.             begin
  1028.             writeln('/', '*');
  1029.             writeln('**    Definitions for argv-operations');
  1030.             writeln('*', '/');
  1031.             writeln(inttyp, tab1, 'argc;');        (* OS *)
  1032.             writeln(chartyp, tab1, '**argv;');
  1033.             writeln(' void');
  1034.             writeln('Argvgt(n, cp, l)');
  1035.             writeln(inttyp, tab1, 'n;');
  1036.             writeln(registr, inttyp, tab1, 'l;');
  1037.             writeln(registr, chartyp, tab1, '*cp;');
  1038.             writeln('{');
  1039.             writeln(tab1, registr, chartyp, tab1, '*sp;');
  1040.             writeln;
  1041.             writeln(tab1, 'for (sp = argv[n]; l > 0 && *sp; l--)');
  1042.             writeln(tab2, '*cp++ = *sp++;');
  1043.             writeln(tab1, 'while (l-- > 0)');
  1044.             writeln(tab2, '*cp++ = ', spchr, ';');
  1045.             writeln('}');
  1046.             end;
  1047.         if (tp^.tsubconst <> nil) or (tp^.tsubtype<> nil) or
  1048.             (tp^.tsubvar <> nil) or (tp^.tsubsub <> nil) then
  1049.             begin
  1050.             writeln('/', '*');
  1051.             writeln('**    Start of program definitions');
  1052.             writeln('*', '/');
  1053.             end;
  1054.         econst(tp^.tsubconst);
  1055.         etype(tp^.tsubtype);
  1056.         evar(tp^.tsubvar);
  1057.         if tp^.tsubsub <> nil then
  1058.             writeln;
  1059.         esubr(tp^.tsubsub);
  1060.         if tp^.tsubid <> nil then
  1061.             begin
  1062.             (* program heading was seen *)
  1063.             writeln('/', '*');
  1064.             writeln('**    Start of program code');
  1065.             writeln('*', '/');
  1066.             if use(dargc) or use(dargv) then
  1067.                 begin
  1068.                 writeln('main(_ac, _av)');    (* OS *)
  1069.                 writeln(inttyp, tab1, '_ac;');
  1070.                 writeln(chartyp, tab1, '*_av[];');
  1071.                 writeln('{');
  1072.                 writeln;
  1073.                 writeln(tab1, 'argc = _ac;');
  1074.                 writeln(tab1, 'argv = _av;')
  1075.                 end
  1076.             else begin
  1077.                 writeln('main()');
  1078.                 writeln('{')
  1079.                  end;
  1080.             increment;
  1081.             elabel(tp);
  1082.             estmt(tp^.tsubstmt);
  1083.             indent;
  1084.             writeln('exit(0);');
  1085.             decrement;
  1086.             writeln('}');
  1087.             writeln('/', '*');
  1088.             writeln('**    End of program code');
  1089.             writeln('*', '/')
  1090.             end
  1091.     end;    (* eprogram *)
  1092.  
  1093.     (*    Emit definitions for constant sets    *)
  1094.     procedure econset(tp : treeptr; len : integer);
  1095.  
  1096.     var    i    : integer;
  1097.  
  1098.         function size(tp : treeptr) : integer;
  1099.  
  1100.         var    r, x    : integer;
  1101.  
  1102.         begin
  1103.             r := 0;
  1104.             while tp <> nil do
  1105.                 begin
  1106.                 if tp^.tt = nrange then
  1107.                     x := cvalof(tp^.texpr)
  1108.                 else if tp^.tt = nempty then
  1109.                     x := 0
  1110.                 else
  1111.                     x := cvalof(tp);
  1112.                 if x > r then
  1113.                     r := x;
  1114.                 tp := tp^.tnext
  1115.                 end;
  1116.             size := csetwords(r+1)
  1117.         end;
  1118.  
  1119.         (*    Emit bits in a constant set    *)
  1120.         procedure ebits(tp : treeptr);
  1121.  
  1122.         type    bitset    = set of 0 .. setbits;
  1123.  
  1124.         var    sets    : array [ 0 .. maxsetrange ] of bitset;
  1125.             s, m, n    : integer;
  1126.  
  1127.             procedure eword(s : bitset);
  1128.  
  1129.             const    bitshex    = 4;    (* nr of bits in a hex-digit *)
  1130.  
  1131.             var    n, i    : integer;
  1132.                 x    : 0 .. setbits;
  1133.  
  1134.             begin
  1135.                 n := 0;
  1136.                 while n <= setbits do
  1137.                     n := n + bitshex;
  1138.                 n := n - bitshex;
  1139.                 while n >= 0 do
  1140.                     begin
  1141.                     (* compute 1 hexdigit *)
  1142.                     x := 0;
  1143.                     for i := 0 to bitshex - 1 do
  1144.                         if (n + i) in s then
  1145.                             case i of
  1146.                               0:    x := x + 1;
  1147.                               1:    x := x + 2;
  1148.                               2:    x := x + 4;
  1149.                               3:    x := x + 8
  1150.                             end;(* case *)
  1151.                     (* print it *)
  1152.                     write(hexdig[x]);
  1153.                     n := n - bitshex
  1154.                     end
  1155.             end;
  1156.  
  1157.         begin
  1158.             s := size(tp);
  1159.             for n := 0 to s - 1 do
  1160.                 sets[n] := [];
  1161.             while tp <> nil do
  1162.                 begin
  1163.                 if tp^.tt = nrange then
  1164.                     for m := cvalof(tp^.texpl) to
  1165.                             cvalof(tp^.texpr) do
  1166.                         begin
  1167.                         n := m div (setbits+1);
  1168.                         sets[n] := sets[n] +
  1169.                             [m mod (setbits+1)]
  1170.                         end
  1171.                 else if tp^.tt <> nempty then
  1172.                     begin
  1173.                     m := cvalof(tp);
  1174.                     n := m div (setbits+1);
  1175.                     sets[n] := sets[n] +
  1176.                         [m mod (setbits+1)]
  1177.                     end;
  1178.                 tp := tp^.tnext
  1179.                 end;
  1180.             write(tab1, s:1);
  1181.             for n := 0 to s - 1 do
  1182.                 begin
  1183.                 write(',');
  1184.                 if n mod 6 = 0 then
  1185.                     writeln;
  1186.                 write(tab1, '0x');
  1187.                 eword(sets[n]);
  1188.                 end;
  1189.             writeln
  1190.         end;
  1191.  
  1192.     begin
  1193.         i := 0;
  1194.         while tp <> nil do
  1195.             begin
  1196.             writeln(static, setwtyp, tab1, 'Q', i:1, '[] = {');
  1197.             ebits(tp^.texps);
  1198.             writeln('};');
  1199.             i := i + 1;
  1200.             tp := tp^.tnext
  1201.             end;
  1202.         writeln(static, setwtyp, tab1, '*Conset[] = {');
  1203.         for i := len - 1 downto 1 do
  1204.             begin
  1205.             write(tab1, 'Q', i:1, ',');
  1206.             if i mod 6 = 5 then
  1207.                 writeln
  1208.             end;
  1209.         writeln(tab1, 'Q0');
  1210.         writeln('};');
  1211.     end;
  1212.  
  1213. begin    (* emit *)
  1214.     indnt := 0;
  1215.     varno := 0;
  1216.     conflag := false;
  1217.     setused := false;
  1218.     dropset := false;
  1219.     doarrow := 0;
  1220.     eprogram(top);
  1221.     if usebool then
  1222.         writeln(chartyp, tab1, '*Bools[] = { "false", "true" };');
  1223.     if usescan then
  1224.         begin
  1225.         writeln;
  1226.         writeln(static, voidtyp);
  1227.         writeln('Scanck(n)');
  1228.         writeln(inttyp, tab1, 'n;');
  1229.         writeln('{');
  1230.         writeln(tab1, 'if (n != 1) {');
  1231.         writeln(tab2, voidcast, 'fprintf(stderr, "Bad input\n");');
  1232.         writeln(tab2, 'exit(1);');
  1233.         writeln(tab1, '}');
  1234.         writeln('}')
  1235.         end;
  1236.     if usegetl then
  1237.         begin
  1238.         writeln;
  1239.         writeln(static, voidtyp);
  1240.         writeln('Getl(f)');
  1241.         writeln(' text', tab1, '*f;');
  1242.         writeln('{');
  1243.         writeln(tab1, 'while (f->eoln == 0)');
  1244.         writeln(tab2, 'Getx(*f);');
  1245.         writeln(tab1, 'Getx(*f);');
  1246.         writeln('}')
  1247.         end;
  1248.     if usefopn then
  1249.         begin
  1250.         writeln;
  1251.         writeln(static, 'FILE *');
  1252.         writeln('Fopen(n, m)');
  1253.         writeln(chartyp, tab1, '*n, *m;');
  1254.         writeln('{');
  1255.         writeln(tab1, 'FILE', tab2, '*f;');
  1256.         writeln(tab1, registr, chartyp, tab1, '*s;');
  1257.         writeln(tab1, static, chartyp, tab1, 'ch = ',
  1258.                         quote, 'A', quote, ';');
  1259.         writeln(tab1, static, chartyp, tab1, 'tmp[MAXFILENAME];');
  1260.         writeln(tab1, xtern , inttyp, tab1, 'unlink();'); (* OS *)
  1261.         writeln;
  1262.         writeln(tab1, 'if (n == NULL)');
  1263.         writeln(tab2, 'sprintf(tmp, ', tmpfilename, 'ch++);');
  1264.         writeln(tab1, 'else {');
  1265.         writeln(tab2, 'strncpy(tmp, n, sizeof(tmp));');
  1266.         writeln(tab2, 'for (s = &tmp[sizeof(tmp)-1]; *s == ',
  1267.             spchr, ' || *s == ', nulchr, '; )');
  1268.         writeln(tab3, '*s-- = ', nulchr, ';');
  1269.         writeln(tab2, 'if (tmp[sizeof(tmp)-1]) {');
  1270.         writeln(tab3, voidcast, 'fprintf(stderr, "Too long filename ',
  1271.             quote, '%s', quote, '\n", n);');
  1272.         writeln(tab3, 'exit(1);');
  1273.         writeln(tab2, '}');
  1274.         writeln(tab1, '}');
  1275.         writeln(tab1, 's = tmp;');
  1276.         writeln(tab1, 'if ((f = fopen(s, m)) == NULL) {');
  1277.         writeln(tab2, voidcast,
  1278.                 'fprintf(stderr, "Cannot open: %s\n", s);');
  1279.         writeln(tab2, 'exit(1);');
  1280.         writeln(tab1, '}');
  1281.         writeln(tab1, 'if (n == NULL)');
  1282.         writeln(tab2, 'unlink(tmp);');    (* OS *)
  1283.         writeln(tab1, 'return (f);');
  1284.         writeln('}');
  1285.         writeln(xtern, inttyp, tab1, 'rewind();')
  1286.         end;
  1287.     if setcnt > 0 then
  1288.         econset(setlst, setcnt);
  1289.     if useunion then
  1290.         begin
  1291.         writeln;
  1292.         writeln(static, setptyp);
  1293.         writeln('Union(p1, p2)');
  1294.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1295.         writeln('{');
  1296.         writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1297.         writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1298.         writeln(tab4, 'p3 = sp;');
  1299.         writeln;
  1300.         writeln(tab1, 'j = *p1;');
  1301.         writeln(tab1, '*p3 = j;');
  1302.         writeln(tab1, 'if (j > *p2)');
  1303.         writeln(tab2, 'j = *p2;');
  1304.         writeln(tab1, 'else');
  1305.         writeln(tab2, '*p3 = *p2;');
  1306.         writeln(tab1, 'k = *p1 - *p2;');
  1307.         writeln(tab1, 'p1++, p2++, p3++;');
  1308.         writeln(tab1, 'for (i = 0; i < j; i++)');
  1309.         writeln(tab2, '*p3++ = (*p1++ | *p2++);');
  1310.         writeln(tab1, 'while (k > 0) {');
  1311.         writeln(tab2, '*p3++ = *p1++;');
  1312.         writeln(tab2, 'k--;');
  1313.         writeln(tab1, '}');
  1314.         writeln(tab1, 'while (k < 0) {');
  1315.         writeln(tab2, '*p3++ = *p2++;');
  1316.         writeln(tab2, 'k++;');
  1317.         writeln(tab1, '}');
  1318.         writeln(tab1, 'return (Saveset(sp));');
  1319.         writeln('}')
  1320.         end;
  1321.     if usediff then
  1322.         begin
  1323.         writeln;
  1324.         writeln(static, setptyp);
  1325.         writeln('Diff(p1, p2)');
  1326.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1327.         writeln('{');
  1328.         writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1329.         writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1330.         writeln(tab4, 'p3 = sp;');
  1331.         writeln;
  1332.         writeln(tab1, 'j = *p1;');
  1333.         writeln(tab1, '*p3 = j;');
  1334.         writeln(tab1, 'if (j > *p2)');
  1335.         writeln(tab2, 'j = *p2;');
  1336.         writeln(tab1, 'k = *p1 - *p2;');
  1337.         writeln(tab1, 'p1++, p2++, p3++;');
  1338.         writeln(tab1, 'for (i = 0; i < j; i++)');
  1339.         writeln(tab2, '*p3++ = (*p1++ & ~ (*p2++));');
  1340.         writeln(tab1, 'while (k > 0) {');
  1341.         writeln(tab2, '*p3++ = *p1++;');
  1342.         writeln(tab2, 'k--;');
  1343.         writeln(tab1, '}');
  1344.         writeln(tab1, 'return (Saveset(sp));');
  1345.         writeln('}')
  1346.         end;
  1347.     if useintr then
  1348.         begin
  1349.         writeln;
  1350.         writeln(static, setptyp);
  1351.         writeln('Inter(p1, p2)');
  1352.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1353.         writeln('{');
  1354.         writeln(tab1, registr, inttyp, tab2, 'i, j, k;');
  1355.         writeln(tab1, registr, setptyp, tab2, 'sp = Newset(),');
  1356.         writeln(tab4, 'p3 = sp;');
  1357.         writeln;
  1358.         writeln(tab1, 'if ((j = *p1) > *p2)');
  1359.         writeln(tab2, 'j = *p2;');
  1360.         writeln(tab1, '*p3 = j;');
  1361.         writeln(tab1, 'p1++, p2++, p3++;');
  1362.         writeln(tab1, 'for (i = 0; i < j; i++)');
  1363.         writeln(tab2, '*p3++ = (*p1++ & *p2++);');
  1364.         writeln(tab1, 'return (Saveset(sp));');
  1365.         writeln('}')
  1366.         end;
  1367.     if usememb then
  1368.         begin
  1369.         writeln;
  1370.         write(static);
  1371.         printid(defnams[dboolean]^.lid);
  1372.         writeln;
  1373.         writeln('Member(m, sp)');
  1374.         writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1375.         writeln(tab1, registr, setptyp, tab1, 'sp;');
  1376.         writeln('{');
  1377.         writeln(tab1, registr, usigned, inttyp,
  1378.                     tab1, 'i = m / (setbits+1) + 1;');
  1379.         writeln;
  1380.         writeln(tab1, 'if ((i <= *sp) &&',
  1381.                     ' (sp[i] & (1 << (m % (setbits+1)))))');
  1382.         write(tab2, 'return (');
  1383.         printid(defnams[dtrue]^.lid);
  1384.         writeln(');');
  1385.         write(tab1, 'return (');
  1386.         printid(defnams[dfalse]^.lid);
  1387.         writeln(');');
  1388.         writeln('}')
  1389.         end;
  1390.     if useseq or usesne then
  1391.         begin
  1392.         writeln;
  1393.         write(static);
  1394.         printid(defnams[dboolean]^.lid);
  1395.         writeln;
  1396.         writeln('Eq(p1, p2)');
  1397.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1398.         writeln('{');
  1399.         writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1400.         writeln;
  1401.         writeln(tab1, 'i = *p1++;');
  1402.         writeln(tab1, 'j = *p2++;');
  1403.         writeln(tab1, 'while (i != 0 && j != 0) {');
  1404.         writeln(tab2, 'if (*p1++ != *p2++)');
  1405.         write(tab3, 'return (');
  1406.         printid(defnams[dfalse]^.lid);
  1407.         writeln(');');
  1408.         writeln(tab2, 'i--, j--;');
  1409.         writeln(tab1, '}');
  1410.         writeln(tab1, 'while (i != 0) {');
  1411.         writeln(tab2, 'if (*p1++ != 0)');
  1412.         write(tab3, 'return (');
  1413.         printid(defnams[dfalse]^.lid);
  1414.         writeln(');');
  1415.         writeln(tab2, 'i--;');
  1416.         writeln(tab1, '}');
  1417.         writeln(tab1, 'while (j != 0) {');
  1418.         writeln(tab2, 'if (*p2++ != 0)');
  1419.         write(tab3, 'return (');
  1420.         printid(defnams[dfalse]^.lid);
  1421.         writeln(');');
  1422.         writeln(tab2, 'j--;');
  1423.         writeln(tab1, '}');
  1424.         write(tab1, 'return (');
  1425.         printid(defnams[dtrue]^.lid);
  1426.         writeln(');');
  1427.         writeln('}')
  1428.         end;
  1429.     if usesne then
  1430.         begin
  1431.         writeln;
  1432.         write(static);
  1433.         printid(defnams[dboolean]^.lid);
  1434.         writeln;
  1435.         writeln('Ne(p1, p2)');
  1436.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1437.         writeln('{');
  1438.         write(tab1, 'return (!Eq(p1, p2));');
  1439.         writeln('}')
  1440.         end;
  1441.     if usesle then
  1442.         begin
  1443.         writeln;
  1444.         write(static);
  1445.         printid(defnams[dboolean]^.lid);
  1446.         writeln;
  1447.         writeln('Le(p1, p2)');
  1448.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1449.         writeln('{');
  1450.         writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1451.         writeln;
  1452.         writeln(tab1, 'i = *p1++;');
  1453.         writeln(tab1, 'j = *p2++;');
  1454.         writeln(tab1, 'while (i != 0 && j != 0) {');
  1455.         writeln(tab2, 'if ((*p1++ & ~ *p2++) != 0)');
  1456.         write(tab3, 'return (');
  1457.         printid(defnams[dfalse]^.lid);
  1458.         writeln(');');
  1459.         writeln(tab2, 'i--, j--;');
  1460.         writeln(tab1, '}');
  1461.         writeln(tab1, 'while (i != 0) {');
  1462.         writeln(tab2, 'if (*p1++ != 0)');
  1463.         write(tab3, 'return (');
  1464.         printid(defnams[dfalse]^.lid);
  1465.         writeln(');');
  1466.         writeln(tab2, 'i--;');
  1467.         writeln(tab1, '}');
  1468.         write(tab1, 'return (');
  1469.         printid(defnams[dtrue]^.lid);
  1470.         writeln(');');
  1471.         writeln('}')
  1472.         end;
  1473.     if usesge then
  1474.         begin
  1475.         writeln;
  1476.         write(static);
  1477.         printid(defnams[dboolean]^.lid);
  1478.         writeln;
  1479.         writeln('Ge(p1, p2)');
  1480.         writeln(tab1, registr, setptyp, tab1, 'p1, p2;');
  1481.         writeln('{');
  1482.         writeln(tab1, registr, inttyp, tab1, 'i, j;');
  1483.         writeln;
  1484.         writeln(tab1, 'i = *p1++;');
  1485.         writeln(tab1, 'j = *p2++;');
  1486.         writeln(tab1, 'while (i != 0 && j != 0) {');
  1487.         writeln(tab2, 'if ((*p2++ & ~ *p1++) != 0)');
  1488.         writeln(tab3, 'return (false);');
  1489.         writeln(tab2, 'i--, j--;');
  1490.         writeln(tab1, '}');
  1491.         writeln(tab1, 'while (j != 0) {');
  1492.         writeln(tab2, 'if (*p2++ != 0)');
  1493.         write(tab3, 'return (');
  1494.         printid(defnams[dfalse]^.lid);
  1495.         writeln(');');
  1496.         writeln(tab2, 'j--;');
  1497.         writeln(tab1, '}');
  1498.         write(tab1, 'return (');
  1499.         printid(defnams[dtrue]^.lid);
  1500.         writeln(');');
  1501.         writeln('}')
  1502.         end;
  1503.     if usemksub then
  1504.         begin
  1505.         writeln;
  1506.         writeln(static, setptyp);
  1507.         writeln('Mksubr(lo, hi, sp)');
  1508.         writeln(tab1, registr, usigned, inttyp, tab1, 'lo, hi;');
  1509.         writeln(tab1, registr, setptyp, tab1, 'sp;');
  1510.         writeln('{');
  1511.         writeln(tab1, registr, inttyp, tab1, 'i, k;');
  1512.         writeln;
  1513.         writeln(tab1, 'if (hi < lo)');
  1514.         writeln(tab2, 'return (sp);');
  1515.         writeln(tab1, 'i = hi / (setbits+1) + 1;');
  1516.         writeln(tab1, 'for (k = *sp + 1; k <= i; k++)');
  1517.         writeln(tab2, 'sp[k] = 0;');
  1518.         writeln(tab1, 'if (*sp < i)');
  1519.         writeln(tab2, '*sp = i;');
  1520.         writeln(tab1, 'for (k = lo; k <= hi; k++)');
  1521.         writeln(tab2, 'sp[k / (setbits+1) + 1] |= ',
  1522.                         '(1 << (k % (setbits+1)));');
  1523.         writeln(tab1, 'return (sp);');
  1524.         writeln('}')
  1525.         end;
  1526.     if useins then
  1527.         begin
  1528.         writeln;
  1529.         writeln(static, setptyp);
  1530.         writeln('Insmem(m, sp)');
  1531.         writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1532.         writeln(tab1, registr, setptyp, tab1, 'sp;');
  1533.         writeln('{');
  1534.         writeln(tab1, registr, inttyp, tab1, 'i,');
  1535.         writeln(tab3, tab1, 'j = m / (setbits+1) + 1;');
  1536.         writeln;
  1537.         writeln(tab1, 'if (*sp < j)');
  1538.         writeln(tab2, 'for (i = *sp + 1, *sp = j; i <= *sp; i++)');
  1539.         writeln(tab3, 'sp[i] = 0;');
  1540.         writeln(tab1, 'sp[j] |= (1 << (m % (setbits+1)));');
  1541.         writeln(tab1, 'return (sp);');
  1542.         writeln('}')
  1543.         end;
  1544.     if usesets then
  1545.         begin
  1546.         writeln;
  1547.         writeln(ifndef, 'SETSPACE');
  1548.         writeln(define, 'SETSPACE 256');
  1549.         writeln(endif);
  1550.         writeln(static, setptyp);
  1551.         writeln('Currset(n,sp)');
  1552.         writeln(tab1, inttyp, tab1, 'n;');
  1553.         writeln(tab1, setptyp, tab1, 'sp;');
  1554.         writeln('{');
  1555.         writeln(tab1, static, setwtyp, tab1, 'Space[SETSPACE];');
  1556.         writeln(tab1, static, setptyp, tab1, 'Top = Space;');
  1557.         writeln;
  1558.         writeln(tab1, 'switch (n) {');
  1559.         writeln(tab1, '  case 0:');
  1560.         writeln(tab2, 'Top = Space;');
  1561.         writeln(tab2, 'return (0);');
  1562.         writeln(tab1, '  case 1:');
  1563.         writeln(tab2, 'if (&Space[SETSPACE] - Top <= ',
  1564.                             maxsetrange:1, ') {');
  1565.         writeln(tab3,
  1566.             voidcast, 'fprintf(stderr, "Set-space exhausted\n");');
  1567.         writeln(tab3, 'exit(1);');
  1568.         writeln(tab2, '}');
  1569.         writeln(tab2, '*Top = 0;');
  1570.         writeln(tab2, 'return (Top);');
  1571.         writeln(tab1, '  case 2:');
  1572.         writeln(tab2, 'if (Top <= &sp[*sp])');
  1573.         writeln(tab3, 'Top = &sp[*sp + 1];');
  1574.         writeln(tab2, 'return (sp);');
  1575.         writeln(tab1, '}');
  1576.         writeln(tab1, '/', '* NOTREACHED *', '/');
  1577.         writeln('}')
  1578.         end;
  1579.     if usescpy then
  1580.         begin
  1581.         writeln;
  1582.         writeln(static, voidtyp);
  1583.         writeln('Setncpy(S1, S2, N)');
  1584.         writeln(tab1, registr, setptyp, tab1, 'S1, S2;');
  1585.         writeln(tab1, registr, usigned, inttyp, tab1, 'N;');
  1586.         writeln('{');
  1587.         writeln(tab1, registr, usigned, inttyp, tab1, 'm;');
  1588.         writeln;
  1589.         writeln(tab1, 'N /= sizeof(', setwtyp, ');');
  1590.         writeln(tab1, '*S1++ = --N;');
  1591.         writeln(tab1, 'm = *S2++;');
  1592.         writeln(tab1, 'while (m != 0 && N != 0) {');
  1593.         writeln(tab2, '*S1++ = *S2++;');
  1594.         writeln(tab2, '--N;');
  1595.         writeln(tab2, '--m;');
  1596.         writeln(tab1, '}');
  1597.         writeln(tab1, 'while (N-- != 0)');
  1598.         writeln(tab2, '*S1++ = 0;');
  1599.         writeln('}')
  1600.         end;
  1601.     if usecase then
  1602.         begin
  1603.         writeln;
  1604.         writeln(static, voidtyp);
  1605.         writeln('Caseerror(n)');
  1606.         writeln(tab1, inttyp, tab1, 'n;');
  1607.         writeln('{');
  1608.         writeln(tab1, voidcast,
  1609.             'fprintf(stderr, "Missing case limb: line %d\n", n);');
  1610.         writeln(tab1, 'exit(1);');
  1611.         writeln('}')
  1612.         end;
  1613.     if usemax then
  1614.         begin
  1615.         writeln;
  1616.         writeln(static, inttyp);
  1617.         writeln('Max(m, n)');
  1618.         writeln(tab1, inttyp, tab1, 'm, n;');
  1619.         writeln('{');
  1620.         writeln(tab1, 'if (m > n)');
  1621.         writeln(tab2, 'return (m);');
  1622.         writeln(tab1, 'return (n);');
  1623.         writeln('}')
  1624.         end;
  1625.     if use(dtrunc) then
  1626.         begin
  1627.         writeln(static, inttyp);
  1628.         writeln('Trunc(f)');
  1629.         printid(defnams[dreal]^.lid);
  1630.         writeln(tab1, 'f;');
  1631.         writeln('{');
  1632.         writeln(tab1, 'return f;');
  1633.         writeln('}')
  1634.         end;
  1635.     if use(dround) then
  1636.         begin
  1637.         writeln(static, inttyp);
  1638.         writeln('Round(f)');
  1639.         printid(defnams[dreal]^.lid);
  1640.         writeln(tab1, 'f;');
  1641.         writeln('{');
  1642.         writeln(tab1, xtern, doubletyp, ' floor();');    (* LIB *)
  1643.         writeln(tab1,
  1644.             'return floor(', dblcast, '(0.5+f));');    (* LIB *)
  1645.         writeln('}')
  1646.         end
  1647. end;    (* emit *)
  1648.  
  1649. (*    Initialize all global structures used in translator.        *)
  1650. procedure initialize;
  1651.  
  1652. var    s    : hashtyp;
  1653.     t    : pretyps;
  1654.     d    : predefs;
  1655.  
  1656.     (*    Define names in ctable.                    *)
  1657.     procedure defname(cn : cnames; str : keyword);
  1658.  
  1659.     label    999;
  1660.  
  1661.     var    w    : toknbuf;
  1662.         i    : toknidx;
  1663.  
  1664.     begin
  1665.         unpack(str, w, 1);
  1666.         for i := 1 to keywordlen do
  1667.             if w[i] = space then
  1668.                 begin
  1669.                 w[i] := chr(null);
  1670.                 goto 999
  1671.                 end;
  1672.         w[keywordlen+1] := chr(null);
  1673.     999:
  1674.         ctable[cn] := saveid(w)
  1675.     end;
  1676.  
  1677.     (*    Define predefined identifiers.                *)
  1678.     procedure defid(nt : treetyp; did : predefs; str : keyword);
  1679.  
  1680.     label    999;
  1681.  
  1682.     var    w    : toknbuf;
  1683.         i    : toknidx;
  1684.         tp, tq,
  1685.         tv    : treeptr;
  1686.  
  1687.     begin
  1688.         for i := 1 to keywordlen do
  1689.             if str[i] = space then
  1690.                 begin
  1691.                 w[i] := chr(null);
  1692.                 goto 999
  1693.                 end
  1694.             else
  1695.                 w[i] := str[i];
  1696.         w[keywordlen+1] := chr(null);
  1697.     999:
  1698.         tp := newid(saveid(w));
  1699.         defnams[did] := tp^.tsym;
  1700.         if nt in [ntype, nfunc, nproc] then
  1701.             begin
  1702.             (* predefined types, procedures and functions
  1703.                 are marked with a particular node *)
  1704.             tv := mknode(npredef);
  1705.             tv^.tdef := did;
  1706.             tv^.tobtyp := tnone
  1707.             end
  1708.         else
  1709.             tv := nil; (* predefined constants and variables will
  1710.                     eventually be bound to something *)
  1711.         case nt of
  1712.           nscalar:
  1713.             begin
  1714.             tv := mknode(nscalar);
  1715.             tv^.tscalid := nil;
  1716.             tq := mknode(ntype);
  1717.             tq^.tbind := tv;
  1718.             tq^.tidl := tp;
  1719.             tp := tq
  1720.             end;
  1721.           nconst,
  1722.           ntype,
  1723.           nfield,
  1724.           nvar:
  1725.             begin
  1726.             tq := mknode(nt);
  1727.             tq^.tbind := tv;
  1728.             tq^.tidl := tp;
  1729.             tq^.tattr := anone;
  1730.             tp := tq
  1731.             end;
  1732.           nfunc,
  1733.           nproc:
  1734.             begin
  1735.             tq := mknode(nt);
  1736.             tq^.tsubid := tp;
  1737.             tq^.tsubstmt := tv;
  1738.             tq^.tfuntyp := nil;
  1739.             tq^.tsubpar := nil;
  1740.             tq^.tsublab := nil;
  1741.             tq^.tsubconst := nil;
  1742.             tq^.tsubtype := nil;
  1743.             tq^.tsubvar := nil;
  1744.             tq^.tsubsub := nil;
  1745.             tq^.tscope := nil;
  1746.             tq^.tstat := 0;
  1747.             tp := tq
  1748.             end;
  1749.           nid:
  1750.         end;(* case *)
  1751.         deftab[did] := tp
  1752.     end;    (* defid *)
  1753.  
  1754.     (*    Define keywords.                    *)
  1755.     procedure defkey(s : symtyp; w : keyword);
  1756.  
  1757.     var    i    : 1 .. keywordlen;
  1758.  
  1759.     begin
  1760.         for i := 1 to keywordlen do
  1761.             if w[i] = space then
  1762.                 w[i] := chr(null);
  1763.         (* relies on symtyp being sorted *)
  1764.         with keytab[ord(s)] do
  1765.             begin
  1766.             wrd := w;
  1767.             sym := s
  1768.             end;
  1769.     end;
  1770.  
  1771.     procedure fixinit(i : strindx);
  1772.  
  1773.     var    t    : toknbuf;
  1774.  
  1775.     begin
  1776.         gettokn(i, t);
  1777.         t[1] := 'i';
  1778.         puttokn(i, t);
  1779.     end;
  1780.  
  1781.     (*    Add a cpu word type description.            *)
  1782.     (*    Parameters lo and hi gives the range of a machine-    *)
  1783.     (*    dependant integer type. Parameter str gives the corres-    *)
  1784.     (*    ponding C-language type-name.                *)
  1785.     procedure defmach(lo, hi : integer; str : machdefstr);
  1786.  
  1787.     label    999;
  1788.  
  1789.     var    i    : toknidx;
  1790.         w    : toknbuf;
  1791.  
  1792.     begin
  1793.         unpack(str, w, 1);
  1794.         if w[machdeflen] <> space then
  1795.             error(ebadmach);
  1796.         for i := machdeflen - 1 downto 1 do
  1797.             if w[i] <> space then
  1798.                 begin
  1799.                 w[i+1] := chr(null);
  1800.                 goto 999
  1801.                 end;
  1802.         error(ebadmach);
  1803.     999:
  1804.         if nmachdefs >= maxmachdefs then
  1805.             error(emanymachs);
  1806.         nmachdefs := nmachdefs + 1;
  1807.         with machdefs[nmachdefs] do
  1808.             begin
  1809.             lolim := lo;
  1810.             hilim := hi;
  1811.             typstr := savestr(w)
  1812.             end
  1813.     end;
  1814.  
  1815.     procedure initstrstore;
  1816.  
  1817.     var    i    : strbcnt;
  1818.  
  1819.     begin
  1820.         for i := 1 to maxblkcnt do
  1821.             strstor[i] := nil;
  1822.         new(strstor[0]);
  1823.         strstor[0]^[0] := chr(null);
  1824.         strfree := 1;
  1825.         strleft := maxstrblk
  1826.     end;
  1827.  
  1828. begin    (* initialize *)
  1829.     lineno := 1;
  1830.     colno := 0;
  1831.  
  1832.     initstrstore;
  1833.  
  1834.     setlst := nil;
  1835.     setcnt := 0;
  1836.     hexdig := '0123456789ABCDEF';
  1837.  
  1838.     symtab := nil;
  1839.     statlvl := 0;
  1840.     maxlevel := -1;
  1841.     enterscope(nil);
  1842.     varno:= 0;
  1843.  
  1844.     usenilp := false;
  1845.  
  1846.     usesets := false;
  1847.     useunion := false;
  1848.     usediff := false;
  1849.     usemksub := false;
  1850.     useintr := false;
  1851.     usesge := false;
  1852.     usesle := false;
  1853.     usesne := false;
  1854.     useseq := false;
  1855.     usememb := false;
  1856.     useins := false;
  1857.     usescpy := false;
  1858.     usefopn := false;
  1859.     usescan := false;
  1860.     usegetl := false;
  1861.  
  1862.     usecase := false;
  1863.     usejmps := false;
  1864.  
  1865.     usebool := false;
  1866.  
  1867.     usecomp := false;
  1868.     usemax    := false;
  1869.  
  1870.     for s := 0 to hashmax do
  1871.         idtab[s] := nil;
  1872.     for d := dabs to dztring do
  1873.         begin
  1874.         deftab[d] := nil;
  1875.         defnams[d] := nil
  1876.         end;
  1877.  
  1878.     (* Pascal keywords *)
  1879.     defkey(sand,    'and       ');
  1880.     defkey(sarray,    'array     ');
  1881.     defkey(sbegin,    'begin     ');
  1882.     defkey(scase,    'case      ');
  1883.     defkey(sconst,    'const     ');
  1884.     defkey(sdiv,    'div       ');
  1885.     defkey(sdo,    'do        ');
  1886.     defkey(sdownto,    'downto    ');
  1887.     defkey(selse,    'else      ');
  1888.     defkey(send,    'end       ');
  1889.     defkey(sextern,    externsym);    (* non-standard *)
  1890.     defkey(sfile,    'file      ');
  1891.     defkey(sfor,    'for       ');
  1892.     defkey(sforward,'forward   ');
  1893.     defkey(sfunc,    'function  ');
  1894.     defkey(sgoto,    'goto      ');
  1895.     defkey(sif,    'if        ');
  1896.     defkey(sinn,    'in        ');
  1897.     defkey(slabel,    'label     ');
  1898.     defkey(smod,    'mod       ');
  1899.     defkey(snil,    'nil       ');
  1900.     defkey(snot,    'not       ');
  1901.     defkey(sof,    'of        ');
  1902.     defkey(sor,    'or        ');
  1903.     defkey(sother,    othersym);    (* non-standard *)
  1904.     defkey(spacked,    'packed    ');
  1905.     defkey(sproc,    'procedure ');
  1906.     defkey(spgm,    'program   ');
  1907.     defkey(srecord,    'record    ');
  1908.     defkey(srepeat,    'repeat    ');
  1909.     defkey(sset,    'set       ');
  1910.     defkey(sthen,    'then      ');
  1911.     defkey(sto,    'to        ');
  1912.     defkey(stype,    'type      ');
  1913.     defkey(suntil,    'until     ');
  1914.     defkey(svar,    'var       ');
  1915.     defkey(swhile,    'while     ');
  1916.     defkey(swith,    'with      ');
  1917.     defkey(seof,    dummysym);    (* dummy entry *)
  1918.  
  1919.     (* C language operator priorities *)
  1920.     cprio[nformat]    := 0;
  1921.     cprio[nrange]    := 0;
  1922.     cprio[nin]    := 0;
  1923.     cprio[nset]    := 0;
  1924.     cprio[nassign]    := 0;
  1925.     cprio[nor]    := 1;
  1926.     cprio[nand]    := 2;
  1927.     cprio[neq]    := 3;
  1928.     cprio[nne]    := 3;
  1929.     cprio[nlt]    := 3;
  1930.     cprio[nle]    := 3;
  1931.     cprio[ngt]    := 3;
  1932.     cprio[nge]    := 3;
  1933.     cprio[nplus]    := 4;
  1934.     cprio[nminus]    := 4;
  1935.     cprio[nmul]    := 5;
  1936.     cprio[ndiv]    := 5;
  1937.     cprio[nmod]    := 5;
  1938.     cprio[nquot]    := 5;
  1939.     cprio[nnot]    := 6;
  1940.     cprio[numinus]    := 6;
  1941.     cprio[nuplus]    := 7;
  1942.     cprio[nindex]    := 7;
  1943.     cprio[nselect]    := 7;
  1944.     cprio[nderef]    := 7;
  1945.     cprio[ncall]    := 7;
  1946.     cprio[nid]    := 7;
  1947.     cprio[nchar]    := 7;
  1948.     cprio[ninteger]    := 7;
  1949.     cprio[nreal]    := 7;
  1950.     cprio[nstring]    := 7;
  1951.     cprio[nnil]    := 7;
  1952.  
  1953.     (* Pascal language operator priorities *)
  1954.     pprio[nassign]    := 0;
  1955.     pprio[nformat]    := 0;
  1956.     pprio[nrange]    := 1;
  1957.     pprio[nin]    := 1;
  1958.     pprio[neq]    := 1;
  1959.     pprio[nne]    := 1;
  1960.     pprio[nlt]    := 1;
  1961.     pprio[nle]    := 1;
  1962.     pprio[ngt]    := 1;
  1963.     pprio[nge]    := 1;
  1964.     pprio[nor]    := 2;
  1965.     pprio[nplus]    := 2;
  1966.     pprio[nminus]    := 2;
  1967.     pprio[nand]    := 3;
  1968.     pprio[nmul]    := 3;
  1969.     pprio[ndiv]    := 3;
  1970.     pprio[nmod]    := 3;
  1971.     pprio[nquot]    := 3;
  1972.     pprio[nnot]    := 4;
  1973.     pprio[numinus]    := 4;
  1974.     pprio[nuplus]    := 5;
  1975.     pprio[nset]    := 6;
  1976.     pprio[nindex]    := 6;
  1977.     pprio[nselect]    := 6;
  1978.     pprio[nderef]    := 6;
  1979.     pprio[ncall]    := 6;
  1980.     pprio[nid]    := 6;
  1981.     pprio[nchar]    := 6;
  1982.     pprio[ninteger]    := 6;
  1983.     pprio[nreal]    := 6;
  1984.     pprio[nstring]    := 6;
  1985.     pprio[nnil]    := 6;
  1986.  
  1987.     (* table of C keywords/functions (which Pascal doesn't know about) *)
  1988.     defname(cabort,        'abort     ');    (* OS *)
  1989.     defname(cbreak,        'break     ');
  1990.     defname(ccontinue,    'continue  ');
  1991.     defname(cdefine,    'define    ');
  1992.     defname(cdefault,    'default   ');
  1993.     defname(cdouble,    'double    ');
  1994.     defname(cedata,        'edata     ');    (* OS *)
  1995.     defname(cenum,        'enum      ');
  1996.     defname(cetext,        'etext     ');    (* OS *)
  1997.     defname(cextern,    'extern    ');
  1998.     defname(cfclose,    'fclose    ');    (* LIB *)
  1999.     defname(cfflush,    'fflush    ');    (* LIB *)
  2000.     defname(cfgetc,        'fgetc     ');    (* LIB *)
  2001.     defname(cfloat,        'float     ');
  2002.     defname(cfloor,        'floor     ');    (* OS *)
  2003.     defname(cfprintf,    'fprintf   ');    (* LIB *)
  2004.     defname(cfputc,        'fputc     ');    (* LIB *)
  2005.     defname(cfread,        'fread     ');    (* LIB *)
  2006.     defname(cfscanf,    'fscanf    ');    (* LIB *)
  2007.     defname(cfwrite,    'fwrite    ');    (* LIB *)
  2008.     defname(cgetc,        'getc      ');    (* OS *)
  2009.     defname(cgetpid,    'getpid    ');    (* OS *)
  2010.     defname(cint,        'int       ');
  2011.     defname(cinclude,    'include   ');
  2012.     defname(clong,        'long      ');
  2013.     defname(clog,        'log       ');    (* OS *)
  2014.     defname(cmain,        'main      ');
  2015.     defname(cmalloc,    'malloc    ');    (* LIB *)
  2016.     defname(cprintf,    'printf    ');    (* LIB *)
  2017.     defname(cpower,        'pow       ');    (* OS *)
  2018.     defname(cputc,        'putc      ');    (* LIB *)
  2019.     defname(cread,        'read      ');    (* OS *)
  2020.     defname(creturn,    'return    ');
  2021.     defname(cregister,    'register  ');
  2022.     defname(crewind,    'rewind    ');    (* LIB *)
  2023.     defname(cscanf,        'scanf     ');    (* LIB *)
  2024.     defname(csetbits,    'setbits   ');
  2025.     defname(csetword,    'setword   ');
  2026.     defname(csetptr,    'setptr    ');
  2027.     defname(cshort,        'short     ');
  2028.     defname(csigned,    'signed    ');
  2029.     defname(csizeof,    'sizeof    ');
  2030.     defname(csprintf,    'sprintf   ');    (* LIB *)
  2031.     defname(cstatic,    'static    ');
  2032.     defname(cstdin,        'stdin     ');    (* LIB *)
  2033.     defname(cstdout,    'stdout    ');    (* LIB *)
  2034.     defname(cstderr,    'stderr    ');    (* LIB *)
  2035.     defname(cstrncmp,    'strncmp   ');    (* OS *)
  2036.     defname(cstrncpy,    'strncpy   ');    (* OS *)
  2037.     defname(cstruct,    'struct    ');
  2038.     defname(cswitch,    'switch    ');
  2039.     defname(ctypedef,    'typedef   ');
  2040.     defname(cundef,        'undef     ');
  2041.     defname(cungetc,    'ungetc    ');    (* LIB *)
  2042.     defname(cunion,        'union     ');
  2043.     defname(cunlink,    'unlink    ');    (* OS *)
  2044.     defname(cunsigned,    'unsigned  ');
  2045.     defname(cwrite,        'write     ');    (* OS *)
  2046.  
  2047.     (* create predefined identifiers *)
  2048.     defid(nfunc,    dabs,        'abs       ');
  2049.     defid(nfunc,    darctan,    'arctan    ');
  2050.     defid(nvar,    dargc,        'argc      ');    (* OS *)
  2051.     defid(nproc,    dargv,        'argv      ');    (* OS *)
  2052.     defid(nscalar,    dboolean,    'boolean   ');
  2053.     defid(ntype,    dchar,        'char      ');
  2054.     defid(nfunc,    dchr,        'chr       ');
  2055.     defid(nproc,    dclose,        'close     ');    (* OS *)
  2056.     defid(nfunc,    dcos,        'cos       ');
  2057.     defid(nproc,    ddispose,    'dispose   ');
  2058.     defid(nid,    dfalse,        'false     ');
  2059.     defid(nfunc,    deof,        'eof       ');
  2060.     defid(nfunc,    deoln,        'eoln      ');
  2061.     defid(nproc,    dexit,        'exit      ');    (* OS *)
  2062.     defid(nfunc,    dexp,        'exp       ');
  2063.     defid(nproc,    dflush,        'flush     ');    (* OS *)
  2064.     defid(nproc,    dget,        'get       ');
  2065.     defid(nproc,    dhalt,        'halt      ');    (* OS *)
  2066.     defid(nvar,    dinput,        'input     ');
  2067.     defid(ntype,    dinteger,    'integer   ');
  2068.     defid(nfunc,    dln,        'ln        ');
  2069.     defid(nconst,    dmaxint,    'maxint    ');
  2070.     defid(nproc,    dmessage,    'message   ');    (* OS *)
  2071.     defid(nproc,    dnew,        'new       ');
  2072.     defid(nfunc,    dodd,        'odd       ');
  2073.     defid(nfunc,    dord,        'ord       ');
  2074.     defid(nvar,    doutput,    'output    ');
  2075.     defid(nproc,    dpack,        'pack      ');
  2076.     defid(nproc,    dpage,        'page      ');
  2077.     defid(nfunc,    dpred,        'pred      ');
  2078.     defid(nproc,    dput,        'put       ');
  2079.     defid(nproc,    dread,        'read      ');
  2080.     defid(nproc,    dreadln,    'readln    ');
  2081.     defid(ntype,    dreal,        'real      ');
  2082.     defid(nproc,    dreset,        'reset     ');
  2083.     defid(nproc,    drewrite,    'rewrite   ');
  2084.     defid(nfunc,    dround,        'round     ');
  2085.     defid(nfunc,    dsin,        'sin       ');
  2086.     defid(nfunc,    dsqr,        'sqr       ');
  2087.     defid(nfunc,    dsqrt,        'sqrt      ');
  2088.     defid(nfunc,    dsucc,        'succ      ');
  2089.     defid(ntype,    dtext,        'text      ');
  2090.     defid(nid,    dtrue,        'true      ');
  2091.     defid(nfunc,    dtrunc,        'trunc     ');
  2092.     defid(nfunc,    dtan,        'tan       ');
  2093.     defid(nproc,    dunpack,    'unpack    ');
  2094.     defid(nproc,    dwrite,        'write     ');
  2095.     defid(nproc,    dwriteln,    'writeln   ');
  2096.  
  2097.     defid(nfield,    dzinit,        '$nit      ');    (* for internal use *)
  2098.     defid(ntype,    dztring,    '$ztring   ');
  2099.  
  2100.     (* bind constants and variables *)
  2101.     deftab[dboolean]^.tbind^.tscalid := deftab[dfalse];
  2102.     deftab[dfalse]^.tnext := deftab[dtrue];
  2103.     currsym.st := sinteger;
  2104.     currsym.vint := maxint;
  2105.     deftab[dmaxint]^.tbind := mklit;
  2106.     deftab[dargc]^.tbind := deftab[dinteger]^.tbind;
  2107.     deftab[dinput]^.tbind := deftab[dtext]^.tbind;
  2108.     deftab[doutput]^.tbind := deftab[dtext]^.tbind;
  2109.  
  2110.     for t := tnone to terror do
  2111.         begin
  2112.         (* for predefined types: set up pointers to "npredef" nodes
  2113.            describing type, fill in constant identifying type *)
  2114.         case t of
  2115.           tboolean:
  2116.             typnods[t] := deftab[dboolean]; (* scalar type *)
  2117.           tchar:
  2118.             typnods[t] := deftab[dchar]^.tbind;
  2119.           tinteger:
  2120.             typnods[t] := deftab[dinteger]^.tbind;
  2121.           treal:
  2122.             typnods[t] := deftab[dreal]^.tbind;
  2123.           ttext:
  2124.             typnods[t] := deftab[dtext]^.tbind;
  2125.           tstring:
  2126.             typnods[t] := deftab[dztring]^.tbind;
  2127.           tnil,
  2128.           tset,
  2129.           tpoly,
  2130.           tnone:
  2131.             typnods[t] := mknode(npredef);
  2132.           terror:
  2133.             (* no op *)
  2134.         end;(* case *)
  2135.         if t in [tchar, tinteger, treal, ttext, tnone, tpoly,
  2136.                         tstring, tnil, tset] then
  2137.             typnods[t]^.tobtyp := t
  2138.         end;
  2139.  
  2140.     (* fix name and type of field "init" *)
  2141.     fixinit(defnams[dzinit]^.lid^.istr);
  2142.     deftab[dzinit]^.tbind := deftab[dinteger]^.tbind;
  2143.  
  2144.     for d := dabs to dztring do
  2145.         linkup(nil, deftab[d]);
  2146.  
  2147.     deftab[dchr]^.tfuntyp := typnods[tchar];
  2148.  
  2149.     deftab[deof]^.tfuntyp := typnods[tboolean];
  2150.     deftab[deoln]^.tfuntyp := typnods[tboolean];
  2151.     deftab[dodd]^.tfuntyp := typnods[tboolean];
  2152.  
  2153.     deftab[dord]^.tfuntyp := typnods[tinteger];
  2154.     deftab[dround]^.tfuntyp := typnods[tinteger];
  2155.     deftab[dtrunc]^.tfuntyp := typnods[tinteger];
  2156.  
  2157.     deftab[darctan]^.tfuntyp := typnods[treal];
  2158.     deftab[dcos]^.tfuntyp := typnods[treal];
  2159.     deftab[dsin]^.tfuntyp := typnods[treal];
  2160.     deftab[dtan]^.tfuntyp := typnods[treal];
  2161.     deftab[dsqrt]^.tfuntyp := typnods[treal];
  2162.     deftab[dexp]^.tfuntyp := typnods[treal];
  2163.     deftab[dln]^.tfuntyp := typnods[treal];
  2164.  
  2165.     deftab[dsqr]^.tfuntyp := typnods[tpoly];
  2166.     deftab[dabs]^.tfuntyp := typnods[tpoly];
  2167.     deftab[dpred]^.tfuntyp := typnods[tpoly];
  2168.     deftab[dsucc]^.tfuntyp := typnods[tpoly];
  2169.  
  2170.     deftab[dargv]^.tfuntyp := typnods[tnone];
  2171.     deftab[ddispose]^.tfuntyp := typnods[tnone];
  2172.     deftab[dexit]^.tfuntyp := typnods[tnone];
  2173.     deftab[dget]^.tfuntyp := typnods[tnone];
  2174.     deftab[dhalt]^.tfuntyp := typnods[tnone];
  2175.     deftab[dnew]^.tfuntyp := typnods[tnone];
  2176.     deftab[dpack]^.tfuntyp := typnods[tnone];
  2177.     deftab[dput]^.tfuntyp := typnods[tnone];
  2178.     deftab[dread]^.tfuntyp := typnods[tnone];
  2179.     deftab[dreadln]^.tfuntyp := typnods[tnone];
  2180.     deftab[dreset]^.tfuntyp := typnods[tnone];
  2181.     deftab[drewrite]^.tfuntyp := typnods[tnone];
  2182.     deftab[dwrite]^.tfuntyp := typnods[tnone];
  2183.     deftab[dwriteln]^.tfuntyp := typnods[tnone];
  2184.     deftab[dmessage]^.tfuntyp := typnods[tnone];
  2185.     deftab[dunpack]^.tfuntyp := typnods[tnone];
  2186.  
  2187.     (* set up definitions for integer subranges *)
  2188.     nmachdefs := 0;
  2189.     defmach(0,        255,        'unsigned char   '); (* CPU *)
  2190.     defmach(-128,        127,        'char            '); (* CPU *)
  2191.     defmach(0,        65535,        'unsigned short  '); (* CPU *)
  2192.     defmach(-32768,        32767,        'short           '); (* CPU *)
  2193.     defmach(-2147483647,    2147483647,    'long            '); (* CPU *)
  2194. {    defmach(0,        4294967295,    'unsigned long   ');}(* CPU *)
  2195. end;    (* initialize *)
  2196.  
  2197. procedure exit(i : integer); external;    (* OS *)
  2198.  
  2199. (*    Action to take when an error is detected.            *)
  2200. procedure error;
  2201.  
  2202. begin
  2203.     prtmsg(m);
  2204.     exit(1);    (* OS *)
  2205.     goto 9999
  2206. end;
  2207.  
  2208. (*    Action to take when a fatal error is detected.            *)
  2209. procedure fatal;
  2210.  
  2211. begin
  2212.     prtmsg(m);
  2213.     halt        (* OS *)
  2214.     (* goto 9999    *)
  2215. end;
  2216.  
  2217.  
  2218. begin    (* program *)
  2219.     initialize;
  2220.     if echo then
  2221.         writeln('# ifdef PASCAL');
  2222.     parse;
  2223.     if echo then
  2224.         writeln('# else');
  2225.     lineno := 0; lastline := 0;
  2226.     transform;
  2227.     emit;
  2228.     if echo then
  2229.         writeln('# endif');
  2230. 9999:
  2231.     (* the very *)
  2232. end.
  2233.  
  2234.